home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_100
/
191_01
/
clink80.c
< prev
next >
Wrap
C/C++ Source or Header
|
1986-07-08
|
17KB
|
494 lines
/* CLINK/80 v. 6-9-85 compile with -k switch */
/* Linkage of C/80 source code subroutines */
/* Phillip L. Emerson Cleveland State University */
/* first version, 4-24-84 */
/* modified 9-17-84 for some filenames in output */
/* modified 2-20-85 for single pass if keyfile exists*/
/* modified 6-7-85: took out #define DONOTHING, put in
#define LF,SP; simplified a few routines; hashlist
structures now used for both data bases -- library
function intercalls (table1) and program function
calls netted up (table2). Also, routine netup() was
modified to erase its tracks to prevent endless
cycling (stack overflow) with cycling function calls */
/* some modifiable parameters */
#define SAME 0
#define LESS -1
#define MORE 1
#define ONE 1
#define VOID -1
#define NULL 0
#define UNDRSC '\137' /*assumes ASCII*/
#define BELL '\007'
#define APOSTR '\047'
#define QUOTE '\042'
#define BACKSL '\134'
#define LF '\n'
#define SP '\40'
#define BUFSIZ 5000 /*must hold any lib. func.*/
#define NAMSIZ 20 /*max length of func. names*/
#define HASHSIZ 512 /*size of hash table */
#define LINSIZ 140 /*source-code max line ln */
#define FNAMSZ 20 /*max len. of file names */
#define OFFSET 20 /*buff offset for backup */
#define MARGA 10 /*error margin for buff ovfl */
#define MARGB 15 /*error margin for buff ovfl */
#define alloc sbrk /*a C/80 optional primitive alloc */
char progfil[FNAMSZ],libfil[FNAMSZ],keyfil[FNAMSZ],outfil[FNAMSZ];
char *fubuff, *linebuf ;
int prchan,lichan,keychan,ouchan,quotes,apostrs,combal;
/* some functs. before main */
/* next f name into r, from string starting
at p -- return 0 if end reached */
char *funam(p,r) char *p,*r; {char *t,*q,*s,*u; int n;
u = r ;
loop: s = p; r = u ;
while ((*p) && (*p != '(' )) p++ ;
if (*p == NULL) return(NULL) ;
t = p-- ;
while ((*p == ' ' ) && (p > s)) p-- ;
q = p ;
if( !lglname(*q)) { p = ++t ; goto loop ; }
while ( lglname(*q) && (q >= s)) q-- ;
q++ ;
for(n=1; (n < (NAMSIZ-1)) && (q <= p); *r++ = *q++,n++) ;
*r = NULL;
if ((q < s) || (n >= (NAMSIZ-1)) || (n <= 0))
{putstr("error in processing name\n") ;
putstr(u); putchar(LF); exit(); }
if (systn(u)) { p = ++t; goto loop; }
return(++t) ; }
/* list of commen system function names to ignore */
#define SNAMES 19 /* nr of names*/
char *sysnam(n) int n;
{static char *name[] = {
"if","for","while","fclose","fopen","getc",
"putc","write","read","getchar","putchar",
"alloc","return","main","seek","ftell",
"ftellr","exec","switch" } ; return(name[n]) ; }
/* Mod2 counting of apostrophes and quotes */
char quotap(n) char n; {static char last;
if(( n == QUOTE) && (last != BACKSL ) && !apostrs)
quotes = ((quotes+1) % 2) ;
if(( n == APOSTR) && (last != BACKSL) && !quotes)
apostrs=((apostrs+1) % 2) ;
last = n ;
return(n) ; }
/* allocate space for s, store s, and return ptr to it */
char *strsave(s) char *s; {char *p ;
if (((p=alloc(strlen(s)+1)) == VOID) || (p == NULL))
return(NULL) ;
strcpy(p,s); return(p) ; }
/* search for string q on p. rtrn ptr to it if so, null if not*/
char *strison(p,q) char *p,*q; {
for( ; *p ; p++) {if(strisat(p,q)) return(p) ; }
return(NULL) ; }
/* standard getch & ungetch to be used in next routine*/
int getctr ;
char getcbuf[5] ;
char getch()
{ if(getctr) return (getcbuf[--getctr]); return(getc(lichan)) ; }
ungetch(a) char a;
{getcbuf[getctr++] = a; return; }
/* get a char from libchan, ignoring literals & comments */
char gignor()
{ char n,m;
loop1: if ((n=getch()) == VOID) return(VOID) ;
if((n != '/') || quotes || apostrs) return(quotap(n)) ;
if((m=getch()) != '*') {ungetch(m) ; return(quotap(n)) ; }
loop2: while (((m=getch()) != '*') && (m != VOID))
{n=getch(); ungetch(n);
if((m == '/') && (n == '*')) combal++ ; }
if (m == VOID) return(VOID) ;
if((m=getch()) != '/') {ungetch(m) ; goto loop2; }
goto loop1; }
oulab() {putl("/* file ",ouchan);putl(outfil,ouchan);putl(" */\n",ouchan);}
struct list {
char *hashkey ;
char *defntn ;
struct list *next ; } ;
struct list **table1 ;
struct list **table2 ;
/* BEGINNING OF MAIN PROGRAM */
main(argc,argv) int argc; char *argv[];
{ putstr("CLINK/80 v. 6-9-85\n") ;
linebuf = alloc(LINSIZ) ;
table1 = (struct list **) alloc(HASHSIZ*(sizeof(struct list *))) ;
table2 = (struct list **) alloc(HASHSIZ*(sizeof(struct list *))) ;
tabinit() ;
fubuff = alloc(BUFSIZ) ;
if( (fubuff == NULL) || (fubuff == VOID))
{putstr("not enough room for buffer\n"); exit(); }
strcpyn(progfil,argv[1],FNAMSZ-1) ;
strcpyn(libfil,argv[2],FNAMSZ-1) ;
strcpyn(keyfil,argv[3],FNAMSZ-1) ;
strcpyn(outfil,argv[4],FNAMSZ-1) ;
if (argc >= 2)
{ if ( !strison(progfil,"."))
strcpy(progfil+strlen(progfil),".B") ;
if (argc < 5) strcpyc(outfil,progfil,'.') ;
if (argc < 4) strcpy(keyfil,"LIBKEY.B") ;
if (argc < 3) strcpy(libfil,"USRLIB.B") ;
defalt(progfil,keyfil,".B") ;
defalt(progfil,libfil,".B") ;
defalt(progfil,outfil,".C") ;
putchar(LF) ;
putstr(progfil) ; putstr(" program file\n") ;
putstr(libfil) ; putstr(" library file\n") ;
putstr(keyfil) ; putstr(" library key file\n") ;
putstr(outfil) ; putstr(" output file \n") ;
putstr("press RETURN (or ENTER) to proceed, Ctrl-C to abort\n") ;
getchar() ;
hashup() ;
prchan = foptst(progfil,"r") ;
ouchan = foptst(outfil,"w") ;
oulab() ;
buildup(1) ;
}
else
{ putstr("\nlibrary file name? ") ; getstr(libfil) ;
putstr("\nlibrary keys file name? "); getstr(keyfil) ;
putstr("wait -- getting library keys\n") ;
hashup() ;
putstr("output file name? ") ; getstr(outfil) ;
ouchan = foptst(outfil,"w") ; oulab() ;
for (*progfil='1'; (*progfil) && (*progfil != LF) ; )
{ putstr("input file name? -- ") ;
putstr("just press RETURN (or ENTER) if no more ") ;
*progfil = NULL; getstr(progfil) ;
if ( (*progfil) && (*progfil != LF ) )
{prchan = foptst(progfil,"r") ;
putstr("include in output file? (type 0 for no, 1 for yes)\n");
buildup(getint()) ;
}
}
}
tidyup() ;
if (quotes || apostrs || combal)
{ putchar(LF); putstr("quotes mod2: ") ; printd(quotes) ;
putchar(LF); putstr("apostrophes mod2: "); printd(apostrs) ;
putchar(LF) ;
putstr("occurrences of comment delimiters within comments: ") ;
printd(combal) ; putchar(LF) ;
}
putstr("Linked output file is "); putstr(outfil); putstr("\n\n") ;
}
/* END OF MAIN PROGRAM */
/* MANY SUBROUTINES FOLLOW -- some of the more general purpose
ones would ordinarily reside in a library, but this program
is intended to be fairly self-contained
*/
/* Manipulation for defaults on file names */
defalt(fpr,fothr,ext) char *fpr,*fothr,*ext;
{ char *a,temp[FNAMSZ]; int n;
if( !strison(fothr,":") && (a = strison(fpr,":") ) )
{ if ( n = a - fpr)
{ strcpyn(temp,fpr,n+1) ;
strcpy(temp+n+1,fothr) ;
strcpy(fothr,temp) ;
}
}
if( !strison(fothr,".") ) strcpy(fothr+strlen(fothr),ext) ;
}
/* copy t to s up to but not including 1st instance of char c */
strcpyc(s,t,c) char *s,*t,c;
{ while( (*s++ = *t++) != c) ; *(--s) = NULL ; }
/* tabinit,hash,look,insert are FUNCTIONS FOR HASHING FUNCTION CALLS UNDER
FUNCTION NAMES
*/
tabinit()
{int n; for (n=0; n < HASHSIZ ; n++) table1[n] = table2[n]=NULL ;}
hash(s) char *s; {int val;
for (val=0; *s ;) val += *s++; return(val % HASHSIZ) ; }
struct list *look(s,table) char *s; struct list **table;
{struct list *p ;
for (p=table[hash(